package br.com.seimos.flex.component
{
	import flash.events.MouseEvent;
	import mx.collections.ArrayCollection;
	import mx.containers.HBox;
	import mx.controls.Button;
	import mx.controls.DataGrid;
	import mx.events.FlexEvent;
	import mx.events.ScrollEvent;
	import mx.messaging.messages.RemotingMessage;
	import mx.rpc.events.InvokeEvent;
	import mx.rpc.events.ResultEvent;
	import mx.rpc.remoting.mxml.RemoteObject;
	
	public class SDataGrid2 extends DataGrid
	{
		public function SDataGrid2()
		{
			super();
			showScrollTips=true;
			addEventListener(FlexEvent.CREATION_COMPLETE, function(event:FlexEvent):void
			{
				addNavigationTools()
			});
		}
		private var btnMore:Button=new Button();
		private var btnAll:Button=new Button();
		private var pagingArgs:ArrayCollection=new ArrayCollection();
		
		private function addNavigationTools():void
		{
			btnMore.enabled=false;
			btnMore.label="Mais...";
			btnMore.addEventListener(MouseEvent.CLICK, buttonClick_handler);
			btnAll.enabled=false;
			btnAll.label="Todos";
			btnAll.addEventListener(MouseEvent.CLICK, buttonClick_handler);
			var hBox:HBox=new HBox();
			hBox.width=width;
			hBox.addChild(btnMore);
			hBox.addChild(btnAll);
			parent.addChildAt(hBox, parent.getChildIndex(parent.getChildByName(name)) + 1);
		}
		
		//--------------------------------------------------------------------------
		//
		//  Private
		//
		//--------------------------------------------------------------------------
		private function buttonClick_handler(event:MouseEvent):void
		{
			if (event.currentTarget == btnMore)
			{
				pagingArgs.setItemAt(0, 2);
			}
			else
			{
				pagingArgs.setItemAt(1, 2);
			}
			btnMore.enabled=false;
			btnAll.enabled=false;
			_remoteObject.getOperation(operation).send.apply(null, pagingArgs.toArray());
		}
		
		private function addNewPage(event:ResultEvent):void
		{
			if (ArrayCollection(event.result).length)
			{
				ArrayCollection(dataProvider).addAll(event.result as ArrayCollection);
				btnMore.enabled=true;
				btnAll.enabled=true;
			}
			else
			{
				btnMore.enabled=false;
				btnAll.enabled=false;
			}
		}
		
		private function invokeFunction(event:InvokeEvent):void
		{
			if (RemotingMessage(event.message).operation == operation)
			{
				var originalArgs:ArrayCollection=new ArrayCollection();
				for each (var o:Object in RemotingMessage(event.message).body as Array)
				{
					originalArgs.addItem(o);
				}
				originalArgs.addItemAt("pagingOperation", 0);
				
				if (pagingArgs.length && !pagingArgs.getItemAt(1))
				{ // verifica se o serviço que também faz a paginação foi acionado
					pagingArgs.addItemAt(dataProvider.length, 1);
					pagingArgs.addItemAt(0, 2);
					for each (var obj:Object in RemotingMessage(event.message).body as Array)
					{
						pagingArgs.addItem(obj);
					}
					_remoteObject.getOperation(operation).addEventListener(ResultEvent.RESULT, addNewPage);
					addEventListener(ScrollEvent.SCROLL, scroll_handler);
				}
			}
			btnMore.enabled=true;
			btnAll.enabled=true;
		}
		
		private function scroll_handler(event:ScrollEvent):void
		{
			if (dataProvider.length - rowCount <= verticalScrollPosition)
			{
				btnMore.dispatchEvent(new MouseEvent(MouseEvent.CLICK));
				btnMore.enabled=false;
				btnAll.enabled=false;
			}
		}
		//--------------------------------------------------------------------------
		//
		//  Variables
		//
		//--------------------------------------------------------------------------
		private var _remoteObject:RemoteObject;
		
		/**
		 * RemoteObject responsável pela população do dataGrid corrente;
		 *
		 * @return
		 */
		[Bindable]
		public function get remoteObject():RemoteObject
		{
			return _remoteObject;
		}
		
		public function set remoteObject(value:RemoteObject):void
		{
			_remoteObject=value;
			_remoteObject.addEventListener(InvokeEvent.INVOKE, invokeFunction);
		}
		private var _operation:String;
		
		[Bindable]
		public function get operation():String
		{
			return _operation;
		}
		
		public function set operation(value:String):void
		{
			_operation=value;
		}
	}
}